<!doctype html>
<html>
  <head>
    <title>Vue事件修饰符 - 阻止冒泡演示</title>
    <script src="https://unpkg.com/vue@3.4.0"></script>
    <style>
      #app {
        padding: 20px;
        font-family: Arial, sans-serif;
      }
      .outer {
        padding: 50px;
        background: #ffcccb;
        color: #8b0000;
        font-weight: bold;
        margin: 20px 0;
        border-radius: 8px;
        cursor: pointer;
      }
      .inner {
        padding: 30px;
        background: #add8e6;
        color: #000080;
        font-weight: bold;
        border-radius: 6px;
        cursor: pointer;
      }
      .button {
        padding: 10px 20px;
        background: #90ee90;
        color: #006400;
        font-weight: bold;
        cursor: pointer;
        border: none;
        border-radius: 4px;
        font-size: 14px;
      }
      .button:hover {
        background: #7fd67f;
      }
      .log {
        background: #f8f9fa;
        border: 1px solid #dee2e6;
        border-radius: 4px;
        padding: 15px;
        margin: 20px 0;
        max-height: 200px;
        overflow-y: auto;
      }
      .log-item {
        margin: 5px 0;
        padding: 5px;
        background: #e9ecef;
        border-radius: 3px;
        font-size: 14px;
      }
      .section {
        margin: 30px 0;
        padding: 0;
        border: 2px solid #dee2e6;
        border-radius: 8px;
        overflow: hidden;
      }
      .section-header {
        padding: 15px 20px;
        background: #f8f9fa;
        border-bottom: 1px solid #dee2e6;
        cursor: pointer;
        display: flex;
        justify-content: space-between;
        align-items: center;
        transition: background-color 0.3s ease;
      }
      .section-header:hover {
        background: #e9ecef;
      }
      .section-header h3 {
        margin: 0;
        color: #495057;
        font-size: 16px;
      }
      .collapse-icon {
        font-size: 18px;
        color: #6c757d;
        transition: transform 0.3s ease;
      }
      .collapse-icon.expanded {
        transform: rotate(90deg);
      }
      .section-content {
        padding: 10px;
        transition: all 0.3s ease;
        overflow: hidden;
      }
      .section-content.collapsed {
        max-height: 0;
        padding: 0 10px;
        opacity: 0;
      }
      .section-content.expanded {
        max-height: 1000px;
        opacity: 1;
      }
      .clear-btn {
        background: #dc3545;
        color: white;
        border: none;
        padding: 8px 16px;
        border-radius: 4px;
        cursor: pointer;
        margin: 10px 0;
      }
      .clear-btn:hover {
        background: #c82333;
      }
    </style>
  </head>
  <body>
    <div id="app">
      <h2>Vue事件修饰符演示 - 阻止事件冒泡</h2>

      <div class="section">
        <div class="section-header" @click="toggleSection(0)">
          <h3>1. 正常事件冒泡（会触发所有层级的事件）</h3>
          <span class="collapse-icon" :class="{ expanded: sections[0].expanded }">▶</span>
        </div>
        <div class="section-content" :class="{ collapsed: !sections[0].expanded, expanded: sections[0].expanded }">
          <div class="outer" @click="handleOuterClick">
            外层div
            <div class="inner" @click="handleInnerClick">
              内层div
              <button class="button" @click="handleButtonClick">点击按钮</button>
            </div>
          </div>
        </div>
      </div>

      <div class="section">
        <div class="section-header" @click="toggleSection(1)">
          <h3>2. 使用.stop修饰符阻止冒泡</h3>
          <span class="collapse-icon" :class="{ expanded: sections[1].expanded }">▶</span>
        </div>
        <div class="section-content" :class="{ collapsed: !sections[1].expanded, expanded: sections[1].expanded }">
          <div class="outer" @click="handleOuterClickStop">
            外层div
            <div class="inner" @click="handleInnerClickStop">
              内层div
              <button class="button" @click.stop="handleButtonClickStop">点击按钮（阻止冒泡）</button>
            </div>
          </div>
        </div>
      </div>

      <div class="section">
        <div class="section-header" @click="toggleSection(2)">
          <h3>3. 在内层div阻止冒泡</h3>
          <span class="collapse-icon" :class="{ expanded: sections[2].expanded }">▶</span>
        </div>
        <div class="section-content" :class="{ collapsed: !sections[2].expanded, expanded: sections[2].expanded }">
          <div class="outer" @click="handleOuterClickStop2">
            外层div
            <div class="inner" @click.stop="handleInnerClickStop2">
              内层div（阻止冒泡）
              <button class="button" @click="handleButtonClickStop2">点击按钮</button>
            </div>
          </div>
        </div>
      </div>

      <button class="clear-btn" @click="clearLog">清空日志</button>

      <div class="log">
        <h4>事件触发日志：</h4>
        <div v-for="(log, index) in eventLogs" :key="index" class="log-item">{{ log }}</div>
        <div v-if="eventLogs.length === 0" style="color: #6c757d; font-style: italic">
          暂无事件日志
        </div>
      </div>
    </div>

    <script>
      const { createApp, ref } = Vue

      createApp({
        setup() {
          const eventLogs = ref([])
          const sections = ref([
            { expanded: true },   // 第一部分默认展开
            { expanded: false },  // 第二部分默认折叠
            { expanded: false }   // 第三部分默认折叠
          ])

          const addLog = message => {
            const timestamp = new Date().toLocaleTimeString()
            eventLogs.value.push(`[${timestamp}] ${message}`)
            if (eventLogs.value.length > 20) {
              eventLogs.value.shift()
            }
          }

          const clearLog = () => {
            eventLogs.value = []
          }

          const toggleSection = (index) => {
            sections.value[index].expanded = !sections.value[index].expanded
          }

          // 正常冒泡示例
          const handleOuterClick = () => {
            addLog('🔴 外层div被点击（正常冒泡）')
          }

          const handleInnerClick = () => {
            addLog('🔵 内层div被点击（正常冒泡）')
          }

          const handleButtonClick = () => {
            addLog('🟢 按钮被点击（正常冒泡）')
          }

          // 阻止冒泡示例1
          const handleOuterClickStop = () => {
            addLog('🔴 外层div被点击（.stop示例）')
          }

          const handleInnerClickStop = () => {
            addLog('🔵 内层div被点击（.stop示例）')
          }

          const handleButtonClickStop = () => {
            addLog('🟢 按钮被点击（使用.stop阻止冒泡）')
          }

          // 阻止冒泡示例2
          const handleOuterClickStop2 = () => {
            addLog('🔴 外层div被点击（内层阻止冒泡示例）')
          }

          const handleInnerClickStop2 = () => {
            addLog('🔵 内层div被点击（使用.stop阻止冒泡）')
          }

          const handleButtonClickStop2 = () => {
            addLog('🟢 按钮被点击（内层阻止冒泡示例）')
          }

          return {
            eventLogs,
            sections,
            clearLog,
            toggleSection,
            handleOuterClick,
            handleInnerClick,
            handleButtonClick,
            handleOuterClickStop,
            handleInnerClickStop,
            handleButtonClickStop,
            handleOuterClickStop2,
            handleInnerClickStop2,
            handleButtonClickStop2
          }
        }
      }).mount('#app')
    </script>
  </body>
</html>
